home *** CD-ROM | disk | FTP | other *** search
/ The PC-SIG Library 10 / The PC-Sig Library - Shareware for the IBM PC and Compatibles (PC-SIG)(Tenth Edition Disks 1-2804)(1991).iso / PC_SIGCD / 13 / 0 / DISK1304.ZIP / PXLINST.PAS < prev    next >
Pascal/Delphi Source File  |  1988-05-03  |  21KB  |  642 lines

  1. {$R-}    {Range checking off}
  2. {$B-}    {Boolean complete evaluation on}
  3. {$S+}    {Stack checking on}
  4. {$I+}    {I/O checking on}
  5. {$N-}    {No numeric coprocessor}
  6. {$M 32768,16384,65536}
  7.  
  8. program PXLInst (input,output);                                       {.CP38}
  9. {  Creates &/or updates PXL.PRN data file of print control characters for   }
  10. {  use by PXL Pascal X-Ref lister.                                          }
  11. {                                                                           }
  12. {  Allows up to three control characters for six actions:                   }
  13. {                                                                           }
  14. {      (1) underlining on             (2) underlining off,                  }
  15. {      (3) elite off,                 (4) elite off,                        }
  16. {      (5) condensed on               (6) condensed off                     }
  17. {                                                                           }
  18. {  plus                                                                     }
  19. {                                                                           }
  20. {      (7) page control (either by Char #12 or by line count).              }
  21. {                                                                           }
  22. {  Data is stored in of string[3], though the program (like PXL) thinks     }
  23. {  of them as bytes (arrays of [0..4] bytes where [0] shows how many of     }
  24. {  the other 3 are significant).                                            }
  25. {                                                                           }
  26. {  Programmer: R. N. Wisan, 7/6,1985       (Converted for TP4, 1988)        }
  27.  
  28.  
  29. Uses
  30.   CRT,
  31.   DOS;
  32.  
  33. const
  34.    Blank      = '           ';
  35.    Bright     = 14;               {Colors for screen.  Set 'em as you like. }
  36.    Dim        =  2;               {Inverse text will be Background on Dim.  }
  37.    Background =  0;
  38.  
  39. type
  40.    LineType = string[79];
  41.    Str48    = string[48];
  42.    Str11    = string[11];
  43.    Tpface   = (MrkB, MrkE, SmallB,SmallE,CondB,CondE,FF);
  44.    ByteLine = array[0..3] of byte;
  45.    Bytes    = array [MrkB..FF] of ByteLine;
  46.    Fil      = File of ByteLine;
  47. var                                                                   {.CP15}
  48.    I:           integer;
  49.    B,OrigAtt:   byte;
  50.    Ch:          char;
  51.    F:           file of ByteLine;
  52.    T:           TpFace;
  53.    Inst:        Bytes;
  54.    Line:        Str11;
  55.    Changed,
  56.    FFFlag,
  57.    Quit,
  58.    GotFile,
  59.    Extended:    boolean;
  60.    TypeLabel:   array[MrkB..FF] of string[20];
  61.    TypeLine:    array[MrkB..FF] of byte;
  62.    FName,
  63.    HeadLine:    LineType;
  64.    CRet:        string[3];
  65.  
  66. procedure Bip;                                                         {.CP5}
  67. begin
  68.    sound(1760); delay(10); sound(440); delay(30);
  69.    sound(1760); delay(15); nosound
  70. end;
  71.  
  72. procedure Blanklines (Top,Bot: byte);                                  {.CP9}
  73. var
  74.    Col,Row:   byte;
  75. begin
  76.    for Row := Top to Bot do begin
  77.       GotoXY(1,Row);
  78.       for Col := 1 to 79 do write(#32)
  79.    end {for Row}
  80. end; {Blanklines}
  81.  
  82. function CurrentAttribute: byte;                                      {.CP12}
  83. var
  84.    R:    Registers;
  85. begin
  86.    GotoXY(1,pred(WhereY));
  87.    with R do begin
  88.       AH := $08;
  89.       BH := 0;
  90.       Intr($10,R);
  91.       CurrentAttribute := AH
  92.    end {with R}
  93. end; {CurrentAttribute}
  94.  
  95. procedure RestoreScreen(Att: byte);                                   {.CP17}
  96. { Put screen back politely (if Att is the atribute found by CurrentAttribute}
  97. { on entry).  Scrolls up one line to set color, but does not overwrite any  }
  98. { other part of the screen.                                                 }
  99. var
  100.    Filler:    integer;
  101.    R:         Registers;
  102. begin
  103.    GotoXY(1,24);
  104.    with R do begin {Scroll up one line at bottom of screen coloring   }
  105.       AX := $0601;    {BIOS Video Svc 6 in AH, 1 line to scroll in AL }
  106.       CX := $1800;    {Top row 23 in CH, Lft col 0 in CL }
  107.       DX := $194F;    {Bot row 24 in CH, Rt col 79 in CL }
  108.       BH := Att;      {Attribute in BH }
  109.    end; {with R}
  110.    Intr($10,R);    {BIOS Video service}
  111. end; {RestoreScreen}
  112.  
  113. procedure Center(S: LineType; Row: byte);                              {.CP9}
  114. var
  115.    B:    byte;
  116. begin
  117.    BlankLines(Row,Row);
  118.    GotoXY(1,Row);
  119.    for B := 1 to (40 - (length(S) div 2)) do write(#32);
  120.    write(S);
  121. end; {Center}
  122.  
  123. function EnvironLine(LineStart: LineType): LineType;                  {.CP30}
  124. { Searches DOS Environment for line beginning with LineStart        }
  125. { Returns line with LineStart removed it in EnvironLine if found.   }
  126. { Returns "NONE" if not found. }
  127. var
  128.    S:               LineType;
  129.    EnvAdd:          word;
  130.    B:               byte;
  131.    LineFound:       boolean;
  132. begin
  133.    EnvAdd := MemW[PrefixSeg:$2C];
  134.    LineFound := False;
  135.    for B := 1 to ord(LineStart[0]) do LineStart[B] := UpCase(LineStart[B]);
  136.    B := 0;
  137.    repeat
  138.       S := '';
  139.       while Mem[EnvAdd:B]<>0 do begin
  140.          S := S + UpCase(char(Mem[EnvAdd:B]));
  141.          B := succ(B)
  142.       end; {while}
  143.       if pos(LineStart,S)=1 then begin
  144.          delete(S,1,ord(LineStart[0]));
  145.          while S[1] in [' ','='] do delete(S,1,1);
  146.          EnvironLine := S;
  147.          LineFound := True
  148.       end; {if PATH}
  149.       B := succ(B)
  150.    until (S[0]=#0) or LineFound;
  151.    if not LineFound then EnvironLine := 'NONE'
  152. end; {EnvironLine}
  153.  
  154. function FindFile(var FName: LineType): boolean;                       {.CP9}
  155. {Takes File name.  Searches for file on default drive & along DOS PATH.  }
  156. {Reports success or failure in FindFile.                                 }
  157. {If file is found, returns openable FName with successful path prefixed. }
  158. var
  159.    Paths,
  160.    Try:       LineType;
  161.    F:         text;   {File type doesn't matter.  File only reset, not read.}
  162.    GotIt:     boolean;
  163.  
  164.    function Path(var P: LineType): LineType;                          {.CP15}
  165.    {Takes DOS PATH line and peels one path specifier from it.  }
  166.    {Returns specifier in Path, bobtailed DOS PATH line in P.   }
  167.    var
  168.       Chunk:     LineType;
  169.    begin
  170.       Chunk := '';
  171.       while (P[1]<>';') and (P[0]<>#0) do begin
  172.          Chunk := Chunk + P[1];
  173.          delete(P,1,1)
  174.       end; {while not ";"}
  175.       while (P[1]=';') and (P[0]<>#0) do delete(P,1,1);
  176.       if Chunk[ord(Chunk[0])]<>'\' then Chunk := Chunk + '\';
  177.       Path := Chunk
  178.    end; {Path}
  179.  
  180.    function Found(var F: text): boolean;                              {.CP14}
  181.    {Takes file variable, tries to open it.  Closes file if opened. }
  182.    {Reports success or failure in Found.                           }
  183.    begin
  184.       {$I-}
  185.       reset(F);
  186.       {$I+}
  187.       if IOresult=0 then begin
  188.          Found := True;
  189.          close(F);
  190.       end {if 0}
  191.       else
  192.          Found := False;
  193.    end; {Found}
  194.  
  195. begin {FindFile}                                                      {.CP23}
  196.    assign(F,FName);
  197.    if Found(F) then
  198.       GotIt := True
  199.    else begin                                          {Strip all path specs}
  200.       while (pos(':',FName)<>0) or (pos('\',FName)<>0) do
  201.          delete(FName,1,1);
  202.       Paths := EnvironLine('PATH');               {Get PATH from Environment}
  203.       if Paths='NONE' then begin
  204.          assign(F,FName);                     {if no PATH, try default drive}
  205.          GotIt := Found(F)
  206.       end {if NONE}
  207.       else begin                                     {else search along PATH}
  208.          repeat
  209.             Try :=  Path(Paths);
  210.             assign(F,Try + FName);
  211.             GotIt := Found(F)
  212.          until (Try='\') or GotIt;
  213.          if GotIt then FName := Try + FName
  214.       end {else found a PATH}
  215.    end; {else not on default drive}
  216.    FindFile := GotIt;
  217. end; {FindFile}
  218.  
  219. procedure ReadFile;                                                   {.CP19}
  220. var
  221.    I:              integer;
  222.    B:              byte;       C: CHAR;
  223. begin
  224.    FName := 'PXL.PRN';
  225.    if FindFile(Fname) then begin
  226.       assign(F,FName);
  227.       Reset(F);
  228.       for T := MrkB to FF do
  229.          if not Eof(F) then read(F,Inst[T]);
  230.       close(F);
  231.       GotFile := TRUE;
  232.    end {if}
  233.    else Begin
  234.       GotFile := FALSE;
  235.       GotoXY(1,23)
  236.    end; {else}
  237. end; {ReadFile}
  238.  
  239. procedure MakeFile;                                                    {.CP9}
  240. begin
  241.    if FName=''
  242.       then Assign(F,'PXL.PRN')
  243.       else assign(F,FName);
  244.    rewrite(F);
  245.    for T := MrkB to FF do write(F,Inst[T]);
  246.    close(F)
  247. end; {MakeFile}
  248.  
  249. procedure ParseLine(var Line: Str11; var Inst: ByteLine);             {.CP13}
  250. var
  251.    I,X,C:    integer;
  252.    Temp:     string[3];
  253.    B,NBytes: byte;
  254.  
  255.    procedure Strip;
  256.    var
  257.       Ch:          char;
  258.    begin
  259.       while (not (Line[1] in ['0'..'9'])) and (Length(Line)>0) do
  260.          delete(Line,1,1);
  261.    end; {Strip}
  262.  
  263.    procedure GetDigit(var X: integer);                             {.CP20}
  264.    var
  265.       Delimit:       integer;
  266.  
  267.       procedure FindDelimit;
  268.       var
  269.          Limiter:   array[0..3] of byte;
  270.          B:          byte;
  271.       begin {FindDelimit}
  272.          Limiter[1] := pos(',',Line);
  273.          Limiter[2] := pos('/',Line);
  274.          Limiter[3] := pos(' ',Line);
  275.          Limiter[0] := 255;
  276.          for B := 1 to 3 do
  277.             if (Limiter[B]<Limiter[0]) and (Limiter[B]>0) then
  278.                Limiter[0] := Limiter[B];
  279.          if Limiter[0] = 255
  280.             then Delimit := 0
  281.             else Delimit := Limiter[0];
  282.       end; {FindDelimit}
  283.  
  284.    begin {GetDigit}                                                   {.CP12}
  285.       FindDelimit;
  286.       if Delimit=0 then Begin                        {if line has no Delimit}
  287.          Temp := Line;
  288.          Line := ''
  289.       end {if no Delimit}
  290.       else begin                                      {if Line has a Delimit}
  291.          Temp := Copy(Line,1,pred(Delimit));
  292.          delete(Line,1,Delimit);
  293.       end; {if Delimit}
  294.       val(Temp,X,C)
  295.    end; {GetDigit}
  296.  
  297. Begin {ParseLine}                                                     {.CP16}
  298.    Inst[0] := 0;
  299.    if T=FF
  300.       then NBytes := 1
  301.       else NBytes := 3;
  302.    For I := 1 to NBytes do begin
  303.       If length(Line)>0 then Strip;                {Strip leading non-digits}
  304.       If (Length(Line)>0) then Begin
  305.          GetDigit(X);                             {Get 1st digit & Chop Line}
  306.          Inst[0] := I;
  307.          Inst[I] := X mod 256;
  308.       End {if Line not zero}
  309.       Else
  310.          Inst[I] := 255
  311.    End {For I}
  312. End; {ParseLine}
  313.  
  314. Function KbIn: char;                                                  {.CP13}
  315. var
  316.    C:              char;
  317. begin
  318.    C := ReadKey;
  319.    if C<>#0 then
  320.       Extended := False
  321.    else begin         {get extended code}
  322.       Extended := True;
  323.       C := ReadKey;
  324.    end; {else}
  325.    KbIn := C;
  326. end; {KbIn}
  327.  
  328. procedure VideoInv;                                                    {.CP5}
  329. begin
  330.    TextColor(Background);
  331.    TextBackGround(Dim)
  332. end; {VideoInv}
  333.  
  334. procedure VideoNorm;                                                   {.CP5}
  335. begin
  336.    TextColor(Dim);
  337.    TextBackGround(Background)
  338. end; {VideoNorm}
  339.  
  340. procedure Initialize;                                                 {.CP12}
  341. var
  342.    T:      TpFace;
  343. begin
  344.    for T := MrkB to FF do
  345.       Inst[T,0] := 0;
  346.    Quit := False;
  347.    FFFlag := True;
  348.    CRet := #17+#196+#217;
  349.    Changed := False
  350. end; {Initialize}
  351.  
  352. procedure MakeLabels;                                                 {.CP23}
  353. var
  354.    B:     byte;
  355. begin
  356.    Headline := '   Font Style:        ';
  357.    for B := length(HeadLine) to 39 do HeadLine := HeadLine + #32;
  358.    HeadLine := HeadLine + 'Present Data:      ';
  359.    If GotFile then HeadLine := HeadLine + '  In File:';
  360.    TypeLabel[MrkB]   := 'Underlined: start: ';
  361.    TypeLabel[MrkE]   := '            stop:  ';
  362.    TypeLabel[SmallB] := 'Elite:      start: ';
  363.    TypeLabel[SmallE] := '            stop:  ';
  364.    TypeLabel[CondB]  := 'Condensed:  start: ';
  365.    TypeLabel[CondE]  := '            stop:  ';
  366.    TypeLabel[FF]     := 'Page Control:      ';
  367.    TypeLine[MrkB]   :=  7;
  368.    TypeLine[MrkE]   :=  8;
  369.    TypeLine[SmallB] := 10;
  370.    TypeLine[SmallE] := 11;
  371.    TypeLine[CondB]  := 13;
  372.    TypeLine[CondE]  := 14;
  373.    TypeLine[FF]     := 16;
  374. end; {MakeLabels}
  375.  
  376. procedure PrintData (Instruc: Byteline);                              {.CP16}
  377. var
  378.    B:         byte;
  379. begin
  380.    if Instruc[0]=0 then
  381.       write(' [Nothing] ')
  382.    else if (T=FF) and (Instruc[0]=1) and (Instruc[1]=66) then
  383.       write(' 66 [Default]')
  384.    else if (T=FF) and (Instruc[0]=1) and (Instruc[1]=12) then
  385.       write(' 12 [Form Feed]')
  386.    else
  387.       for B := 1 to Instruc[0] do begin
  388.          write(Instruc[B]:3);
  389.          if B<Instruc[0] then write('  ')
  390.       end {for B}
  391. end; {PrintData}
  392.  
  393. procedure LayOut;                                                     {.CP15}
  394.  
  395.    procedure WriteHelpLine;
  396.    begin
  397.       write('Use ');
  398.       TextColor(Bright); write(#27);     VideoNorm; write(', ');
  399.       TextColor(Bright); write(#26);     VideoNorm; write(', ');
  400.       TextColor(Bright); write(#24);     VideoNorm; write(', ');
  401.       TextColor(Bright); write(#25);     VideoNorm; write(', ');
  402.       TextColor(Bright); write('Home');  VideoNorm; write(', ');
  403.       TextColor(Bright); write('End');   VideoNorm; write(', ');
  404.       TextColor(Bright); write('PgUp');  VideoNorm; write(', & ');
  405.       TextColor(Bright); write('PgDn');  VideoNorm; write(' to move, ');
  406.       TextColor(Bright); write('Esc');   VideoNorm; write(' to quit.');
  407.    end; {WriteHelpLine}
  408.  
  409. begin {LayOut}                                                        {.CP22}
  410.    Center('Printer Installation for PXL Pascal Lister',1);
  411.    GotoXY(31,3); write('To exit, press <');
  412.    TextColor(Bright); write('Esc'); VideoNorm; write('>');
  413.    GotoXY(1,5); write(HeadLine);
  414.    for T := MrkB to FF do begin
  415.       GotoXY(1,TypeLine[T]);
  416.       write(TypeLabel[T]);
  417.       GotoXY(40,TypeLine[T]);
  418.       PrintData(Inst[T]);
  419.       if GotFile then begin
  420.          GotoXY(60,TypeLine[T]);
  421.          PrintData(Inst[T])
  422.       end {if GotFile}
  423.    end; {for T}
  424.    if not GotFile then begin
  425.       GotoXY(60,TypeLine[MrkE]);
  426.       write('  --- No File ---')
  427.    end {if not GotFile}
  428.    else
  429.       Center('File is ' + FName, 2);
  430.    GotoXY(10,25);
  431.    WriteHelpLine
  432. end; {Layout}
  433.  
  434. procedure Message;                                                    {.CP32}
  435. begin
  436.    if FFFlag then begin
  437.       GotoXY(5,18);
  438.       write('     Enter the ASCII numbers ('); TextColor(Bright); write('numbers');
  439.       VideoNorm; write(' not characters) of the print     ')
  440.    end; {if FFFlag}
  441.    GotoXY(5,19);
  442.    case T of
  443.       MrkB..SmallE:  write('        ');
  444.       CondB..CondE:  write('      ');
  445.    end; {case}
  446.    write('control symbols your printer needs to ');
  447.    TextColor(Bright);
  448.    case T of
  449.       MrkB:   write('start underlining.        ');
  450.       MrkE:   write('stop underlining.         ');
  451.       SmallB: write('start elite print.        ');
  452.       SmallE: write('stop elite print.         ');
  453.       CondB:  write('start condensed print.    ');
  454.       CondE:  write('stop condensed print.     ');
  455.    end; {case}
  456.    VideoNorm;
  457.    if FFFlag then begin
  458.       Center('    Enter up to 3 numbers, separated by comma,' +
  459.          ' space, or slash (/).     ',21);
  460.       GotoXY(17,22);
  461.       write('Then press <CR> ('); TextColor(Bright); write(CRet);
  462.       VideoNorm; write(') to enter them as data.');
  463.       FFFlag := False
  464.    end {if FFFlag}
  465. end; {Message}
  466.  
  467. procedure FFMessage;                                                  {.CP15}
  468. begin
  469.    GotoXY(5,18);
  470.    write(' If Character #12 makes your printer feed out a fresh page, enter');
  471.       TextColor(Bright); write(' 12 '); VideoNorm;
  472.    GotoXY(5,19);
  473.    write('Otherwise, enter ');
  474.       TextColor(Bright); write('the number of lines you get on a page,');
  475.       VideoNorm; write(' (66 is common)');
  476.    GotoXY(5,21);
  477.    write('   Type a single number.  Then press <CR> ('); TextColor(Bright);
  478.       write(CRet); VideoNorm; write(') to enter it as data.   ');
  479.    if not FFFlag then BlankLines(22,22);
  480.    FFFlag := True
  481. end; {FFMessage}
  482.  
  483. procedure SortExtent(B: char);                                        {.CP14}
  484. begin
  485.    case B of
  486.       'H':     if T=MrkB                     {Up arrow}
  487.                   then T := FF
  488.                   else dec(T);
  489.       'G','I': T := MrkB;                    {Home or PgUp}
  490.       'P':     if T=FF                       {Down arrow}
  491.                   then T := MrkB
  492.                   else inc(T);
  493.       'O','Q': T := FF;                      {End or PgDn}
  494.       else Bip;
  495.    end; {case}
  496. end;
  497.  
  498. procedure GoGetEm;                                                    {.CP13}
  499.  
  500.    procedure ReadLine(var Line:Str11);
  501.  
  502.       procedure BackSpace;
  503.       begin
  504.          if length(Line)>0 then begin
  505.             write(#8,#32,#8);
  506.             delete(Line,length(Line),1)
  507.          end {if length}
  508.          else
  509.             Bip
  510.       end; {BackSpace}
  511.  
  512.       procedure ProcCharacter;                                         {.CP9}
  513.       begin
  514.          if length(Line)<11 then begin
  515.             Line := Line + Ch;
  516.             write(Ch)
  517.          end {if length}
  518.          else
  519.             Bip
  520.       end; {ProcCharacter}
  521.  
  522.    begin {ReadLine}                                                   {.CP18}
  523.       Ch := #0; Extended := False; Line := '';
  524.       while not (Extended or Quit or (WhereX>31)
  525.             or (Ch=#13) or (length(Line)>11)) do begin
  526.          Ch := Kbin;
  527.          if (Ch=#8) or (Extended and (Ch='K')) then begin         {Backspace}
  528.             BackSpace;
  529.             Extended := False
  530.          end {if backspace}
  531.          else if Extended and (Ch='M') then begin               {Right Arrow}
  532.             Ch := #32;
  533.             ProcCharacter;
  534.             Extended := False
  535.          end {else if Rt arrow}
  536.          else if Ch=#27 then Quit := True                            {Escape}
  537.          else if not extended and (Ch<>#13) then ProcCharacter     {Reg Char}
  538.       end {While}
  539.    end; {ReadLine}
  540.  
  541.    procedure PrintCurrentLine;                                         {.CP6}
  542.    begin
  543.       GotoXY(20,TypeLine[T]); for B := 20 to 39 do write(#32);
  544.       PrintData(Inst[T]);
  545.       for B := WhereX to 59 do write(#32);
  546.    end;
  547.  
  548. begin {GoGetEm}                                                       {.CP22}
  549.    T := MrkB;
  550.    while not Quit do begin
  551.       if T = FF then FFMessage else Message;
  552.       GotoXY(20,TypeLine[T]); VideoInv; write(Blank); GotoXY(20,TypeLine[T]);
  553.       ReadLine(Line);
  554.       VideoNorm;
  555.       PrintCurrentLine;
  556.       if Ch=#13 then begin
  557.          Changed := True;
  558.          ParseLine(Line,Inst[T]);
  559.          if (T=FF) and (Inst[T,0]=0) then begin  {FF may not be empty, so   }
  560.             Inst[T,0] := 1;                      {default to 66 (lines/page)}
  561.             Inst[T,1] := 66
  562.          end; {if FF}
  563.          PrintCurrentLine;
  564.          if T=FF
  565.             then T := MrkB
  566.             else inc(T);
  567.       end {if CR}
  568.       else if Extended then
  569.          SortExtent(Ch);
  570.    end; {while}
  571. end; {GoGetEm}
  572.  
  573. procedure SaveIt;                                                      {.CP8}
  574. begin
  575.    MakeFile;
  576.    if GotFile then
  577.       Center('Okay, data in PXL.PRN updated',22)
  578.    else
  579.       Center('Okay, new PXL.PRN file created & data stored in it',22)
  580. end; {SaveIt}
  581.  
  582. procedure QuitIt;                                                      {.CP7}
  583. begin
  584.    if GotFile then
  585.       Center('Okay, new data are ignored.  PXL.PRN is unchanged.',22)
  586.    else
  587.       Center('Okay, new data are ignored.  No PXL.PRN created.',22)
  588. end; {QuitIt}
  589.  
  590. procedure AskSave;                                                    {.CP27}
  591. const
  592.    Answers: set of char = ['Y','N'];
  593.    Yesses: set of char = ['Y','y'];
  594. var
  595.    Ch:        char;
  596. begin {AskSave}
  597.    BlankLines(18,24);
  598.    repeat
  599.       if GotFile then
  600.          Center('Do you want PXL.PRN updated with this new data?  ',20)
  601.       else
  602.          Center('Do you want this data saved in PXL.PRN?  ',20);
  603.       Ch := UpCase(ReadKey);
  604.       if not (Ch in Answers) then begin
  605.          BlankLines(19,19);
  606.          Bip;
  607.          gotoXY(5,19);
  608.          write('You must answer ');
  609.          TextColor(Bright); write('Y');
  610.          VideoNorm; write(' or ');
  611.          TextColor(Bright); write('N');
  612.          VideoNorm; write(':')
  613.       end {if not answer}
  614.       else
  615.          write(Ch)
  616.    until Ch in Answers;
  617.    if Ch in Yesses then SaveIt else QuitIt (* := True else Save := False*)
  618. end; {AskSave}
  619.  
  620. procedure PartFriends;
  621. begin
  622.    BlankLines(18,24);
  623.    Center('Nothing changed.  Nothing saved.',20);
  624.    Center('Nothing venture, nothing win.',21)
  625. end; {PartFriends}
  626.  
  627. begin {install main}                                                  {.CP18}
  628.    OrigAtt := CurrentAttribute;
  629.    CheckBreak := False;
  630.    VideoNorm;
  631.    ClrScr;
  632.    Initialize;
  633.    ReadFile;
  634.    MakeLabels;
  635.    LayOut;
  636.    GoGetEm;
  637.    if Changed
  638.       then AskSave
  639.       else PartFriends;
  640.    RestoreScreen(OrigAtt);
  641. end.
  642.